package br.affero.web.controller;

import java.io.Serializable;
import java.util.Date;

import javax.enterprise.inject.Produces;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

import org.jboss.solder.logging.Logger;

import br.affero.core.person.dao.PersonDao;
import br.affero.core.person.model.Experience;
import br.affero.core.person.model.Person;
import br.affero.util.JsfUtil;

/**
 * Controller que trabalha com o detalhe de dados de uma pessoa
 * 
 * Ações definidas: 
 *   * detailSetup   : Obtem detalhe da pessoa e redireciona para tela consulta 
 *   * editSetup     : Obtem detalhe da pessoa e redireciona para tela edição
 *   * newSetup      : Inicializa dados nova pessoa e redireciona para tela edição
 *   * edit          : Operação que Salva dados alterados
 *   * newExperience : Adiciona no cadastro experiência em branco (não salva experiencia no banco)
 *   * getPerson     : Obter objeto pessoa para alteração de dados 
 * 
 * @author Paulo
 * 
 */
@Named
@ViewScoped
public class PersonDetailController implements Serializable {
    //@Inject
    //private Logger logger;
    private static Logger logger = Logger.getLogger(PersonDetailController.class);
    private static final String GENERIC_ERROR = "Ocorreu um erro genérico!";
    
    private Person person;
    
    @Inject
	PersonDao personDao;
    
    
   
    
    /**
     * Valida data de nascimento
     * @param context contexto faces
     * @param toValidate 
     * @param value data de nascimento digitada
     */
    public void validateBirthDate(FacesContext context, UIComponent toValidate, Object value) {  
        Date now = new Date();
        Date birthDate = (Date) value;   
      
        if (birthDate.getTime() > now.getTime()) {
            ((UIInput)toValidate).setValid(false);  
      
            JsfUtil.addErrorMessage(context, toValidate.getClientId(context), " *A data nascimento não pode ser futura ");
        }  
    }
    
    /**
     * Inicializa dados para visualização detalhe da pessoa (consulta de dados)
     * @return String ação que envia para a tela de consulta detalhe pessoa
     */
    public String detailSetup() {
            FacesContext context = FacesContext.getCurrentInstance();
            try {
                    person = context.getApplication().evaluateExpressionGet(context,
                                    "#{item}", Person.class);
            } catch (Exception e) {
                    logger.error(GENERIC_ERROR,e);
                    JsfUtil.addErrorMessage(GENERIC_ERROR);
            }
            
            return "person_detail";
    }
    
    /**
     * Inicializa dados para edição do detalhe da pessoa 
     * @return String próxima ação do jsf
     */
    public String editSetup() {
            FacesContext context = FacesContext.getCurrentInstance();
            
            try {           
                    person = context.getApplication().evaluateExpressionGet(context,
                                    "#{item}", Person.class);
            } catch (Exception e) {
                    logger.error(GENERIC_ERROR,e);
                    JsfUtil.addErrorMessage(GENERIC_ERROR);
            }
            
            return "person_edit";
    }
    
    /**
     * Inicializa dados para criar nova pessoa
     * @return String ação que envia para tela edição detalhe
     */
    public String newSetup() {
            person = new Person();
            person.setActive(true);
            
            return "person_edit";
    }
    
    /**
     * Salva dados alterados
     * @return String ação que envia para tela listagem de pessoas
     */
    public String edit() {          
            
            try {
                    personDao.saveOrUpdate(person);
                    JsfUtil.addSuccessMessage("Pessoa " + person.getName() + " salva com sucesso!");         
            } catch (Exception e) {
                    logger.error(GENERIC_ERROR,e);
                    JsfUtil.addErrorMessage(GENERIC_ERROR);
            }
            
            return "person_list";
    }


    /**
     * Adiciona nova experiencia à pessoa (sem salvar no banco)
     * @return String ação que envia para a tela edição detalhe
     */
    public String newExperience() {
            try {
                    person.getPersonExperiences().add(new Experience());
            }  catch (Exception e) {
                    logger.error(GENERIC_ERROR,e);
                    JsfUtil.addErrorMessage(GENERIC_ERROR);
            }
            
            return "person_edit";
    }
    
    /**
     * Exclui experiencia da pessoa (sem salvar no banco)
     * @return String ação que envia para a tela edição detalhe
     */
    public String deleteExperience() {
            FacesContext context = FacesContext.getCurrentInstance();
            try {
                    Experience experience = context.getApplication().evaluateExpressionGet(context,
                                    "#{personExperience}", Experience.class);
                    person.getPersonExperiences().remove(experience);
                    
            }  catch (Exception e) {
                    logger.error(GENERIC_ERROR,e);
                    JsfUtil.addErrorMessage(GENERIC_ERROR);
            }
            
            return "person_edit";
    }
    
    /**
     * Obtem pessoa a ser trabalha (edição de dados)
     * @return Person pessoa a ser trabalhada 
     */
    @Produces
    public Person getPerson() {
            return person;
    }
}
